|
このテクニカルノートは、AEBuild * ルーチン群およびそれらが受け付ける簡単なアップルイベント記述言語について説明します。さらに、AEPrint ルーチンについて gdb 内での使用方法とともに説明します。
AEBuild * ルーチン群は、別のアプリケーションに情報を送るためにメモリ内で複雑なアップルイベント構造体を構築する、簡単に使えて保守のしやすい機能を提供します。AEPrint は、複雑なアップルイベント構造体を、AEBuild * が認識できる文字列と同じ構文を使う書式の文字列として表示する、AEBuild * に対応した書式付き出力ルーチンを提供します。
このテクニカルノートは、アプリケーションの中で高度なアップルイベント構造体を頻繁に利用するアプリケーション開発者に向けて書かれたものです。
[2002 年 5 月 21 日]
|
はじめに
AEBuild * ルーチンは、専用の書式を持つ文字列を複雑なアップルイベントディスクリプタに変換する非常に簡単な変換サービスを提供します。複雑なアップルイベントディスクリプタレコードの作成には通常、ディスクリプタを 1 つ 1 つ構築していくために Apple Event Manger ルーチンを何度も呼び出す必要があります。AEBuild * ルーチンを使えば、複雑なアップルイベントディスクリプタを構築するのに必要なすべての呼び出しを、指定する書式指定文字列に従った望みの構造体を作成する 1 つのシステム呼び出しに統合できます。
AEPrint は、アップルイベントディスクリプタレコードの内容を表示するために、AEBuild * に対応する書式付き出力ルーチンを提供します。AEPrint により作成された文字列は、AEBuild が受け付ける文字列と書式が同じです。AEPrint は、アップルイベントルーチンのデバッグ時、アップルイベントディスクリプタレコードを表示するのに非常に役立ちます。
AEBuild * ルーチンは多くの点で、標準 C ライブラリの *printf ルーチン群と非常に似ています。指定する書式指定文字列の構文は、非常に簡単でありながら、これによりデータ項目をアップルイベントディスクリプタへ組み込むことができるようになります。本文書の残りの部分では AEBuild * ルーチン群について、およびそれらルーチン群に使用できるディスクリプタ文字列の構文について説明します。
先頭に戻る
AEBuild を使ったディスクリプタレコードの構築
AEBuildDesc
AEBuildDesc は、AEBuild のディスクリプタ文字列をアップルイベントディスクリプタレコード(AEDesc )にコンパイルする機能を提供します。パラメータは次のとおりです。
OSStatus AEBuildDesc(
AEDesc* dst,
AEBuildError* error, /* NULL の場合もある */
const char* src,
...);
パラメータ:
dst - 作成するディスクリプタを保存する AEDesc レコードへのポインタ。
error - 発生するすべてのエラーに関する詳細情報が保存される AEBuildError 構造体へのポインタ。このパラメータは省略可能であり、この情報が必要なければ、代わりに NULL を渡しても構いません。
src - 作成する AEDesc レコードについて記述する AEBuild 書式指定文字列。
... - src パラメータに渡す書式指定文字列が必要とする任意の数のパラメータ。
結果:
AEBuildDesc の呼び出しの成否を数値で表す結果コード。値 AEBuildSyntaxNoErr (ゼロ)は、呼び出しの成功を意味します。error パラメータを使えば、ほかのエラーに関する情報を知ることができます。
|
先頭に戻る
AEBuildError
AEBuildError は、エラーに関する詳細情報を調べるために、AEBuild * ルーチンに渡すことができる構造体を定義します。AEBuild * ルーチンは、省略可能な error パラメータの中でこの構造体へのポインタを受け取ります。ディスクリプタ文字列をデバッグするときは、このパラメータを使ってディスクリプタ文字列の中で見つかったエラーに関するより完全な情報を取得できます。AEBuildError 構造体は次のように宣言されています。
typedef UInt32 AEBuildErrorCode;
struct AEBuildError {
AEBuildErrorCode fError;
UInt32 fErrorPos;
};
typedef struct AEBuildError AEBuildError;
|
この構造体の目的は、ディスクリプタ文字列の解析中に発生するエラーに関する詳細情報を提供することです。fError フィールドには、表 1 に示す値の 1 つが含まれ、fErrorPos フィールドには、文字列の中でパーサーがエラーを検出した文字の位置が含まれます。
表 1 AEBuild の拡張エラーコード
定数名
|
値
|
説明
|
AEBuildSyntaxNoErr
| 0 | エラーなし |
AEBuildSyntaxBadToken
| 1 | 不正な文字 |
AEBuildSyntaxBadEOF
| 2 | 書式指定文字列の不正終了 |
AEBuildSyntaxNoEOF
| 3 | 終端を越える不正文字列 |
AEBuildSyntaxBadNegative
| 4 | - の後に数字がない |
AEBuildSyntaxMissingQuote
| 5 | 閉じる記号 ' が欠落 |
AEBuildSyntaxBadHex
| 6 | 16 進数の文字列に数字でない文字がある |
AEBuildSyntaxOddHex
| 7 | 16 進数の値の桁数が奇数 |
AEBuildSyntaxNoCloseHex
| 8 | $ または » が欠落 |
AEBuildSyntaxUncoercedHex
| 9 | 16 進数の文字列はタイプ変換の必要あり |
AEBuildSyntaxNoCloseString
| 10 | 閉じる引用符が欠落 |
AEBuildSyntaxBadDesc
| 11 | 不正なディスクリプタ |
AEBuildSyntaxBadData
| 12 | (...)内に不正なデータ値 |
AEBuildSyntaxNoCloseParen
| 13 | データ値の後に ) が欠落 |
AEBuildSyntaxNoCloseBracket
| 14 | , または ] が必要 |
AEBuildSyntaxNoCloseBrace
| 15 | , または } が必要 |
AEBuildSyntaxNoKey
| 16 | レコード中にキーワードが欠落 |
AEBuildSyntaxNoColon
| 17 | レコード中のキーワードの後に : が欠落 |
AEBuildSyntaxCoercedList
| 18 | リストはタイプ変換不可 |
AEBuildSyntaxUncoercedDoubleAt
| 19 | @@ による置換にはタイプ変換が必要 |
|
先頭に戻る
vAEBuildDesc (varargs に相当)
vAEBuildDesc ルーチンにより、AEBuildDesc への呼び出しを独自のラッパルーチンでカプセル化できます。ディスクリプタ文字列に使用する、事前に定義した任意の長さの引数パラメータリストへの va_list 参照を vAEBuildDesc に渡します。<stdarg.h> ファイルは、va_list データタイプを宣言して使うためのマクロを定義します。vAEBuildDesc は、AEBuildDesc と同じ機能を提供します。
OSStatus vAEBuildDesc(
AEDesc* dst,
AEBuildError* error, /* NULL の場合もある */
const char* src,
va_list args);
パラメータ:
dst - 作成するディスクリプタを保存する AEDesc レコードへのポインタ。
error - 発生するすべてのエラーに関する詳細情報が保存される AEBuildError 構造体へのポインタ。このパラメータは省略可能であり、この情報が必要なければ、代わりに NULL を渡しても構いません。
src - 作成する AEDesc レコードについて記述する AEBuild の書式指定文字列。
args - vAEBuildDesc に使用される任意の長さの引数リストを参照する va_list 。
結果:
AEBuildDesc の呼び出しの成否を数値で表す結果コード。値 AEBuildSyntaxNoErr (ゼロ)は、呼び出しの成功を意味します。error パラメータを使えば、ほかのエラーに関する情報を知ることができます。
|
任意の長さのパラメータリストを受け付けるその他の AEBuild * ルーチンにもすべて、任意の長さのパラメータリスト('... ')の代わりに va_list args を持つ varags に相当する関数が含まれています。話を簡単にしておくために、これらのルーチンについては完全な定義と説明をする代わりに、次の節で軽く触れるだけにします。なぜなら、それらは可変の引数を持つ対応する関数と同じだからです。
先頭に戻る
AEBuild を使ったアップルイベントレコードの構築
AEBuildAppleEvent に渡される、1 つの完全なアップルイベントのための書式指定文字列の構文は、中括弧を除けば、アップルイベントレコードの内容を表すのに使われる書式指定文字列の構文とほとんど同じです。アップルイベントは、名前/値のペアの並びとして定義され、省略可能なパラメータの前にはチルダ記号(‾ ) が付いています。
AEBuildAppleEvent ルーチンを使えば、1 つの完全なアップルイベントレコードを構築でき、AEBuildParameters ルーチンを使えば、既存のアップルイベントレコードにパラメータを追加できます。本節では、これら 2 つのルーチンについて説明します。
AEBuildAppleEvent
AEBuildAppleEvent ルーチンを使えば、1 回の呼び出しでアップルイベントレコードを構築できます。このルーチンは、AppleEvent レコードの作成に加え最後の 3 つの引数に基づいてイベントのためのパラメータを構築する点を除けば、AECreateAppleEvent ルーチンと機能が非常に似ています。AECreateAppleEvent ルーチンの詳細については、Apple Event Manager に関する文献を参照してください。
OSStatus AEBuildAppleEvent(
AEEventClass theClass,
AEEventID theID,
DescType addressType,
const void* addressData,
long addressLength,
short returnID,
long transactionID,
AppleEvent* result,
AEBuildError* error, /* NULL の場合もある*/
const char* paramsFmt,
...);
注意:AEBuildAppleEvent には、vAEBuildAppleEvent という varargs と同等の関数があります。
パラメータ:
theClass - 作成するアップルイベントのイベントクラス。
theID - 作成するアップルイベントのイベント ID。
addressType - 次の 2 つのパラメータに記述するアドレス情報のアドレスタイプ。通常は、typeApplSignature 、typeProcessSerialNumber 、またはtypeKernelProcessID のどれかです。
addressData - アドレス情報へのポインタ。
addressLength - addressData パラメータが指すデータのバイト数。
returnID - 通常は、値 kAutoGenerateReturnID に設定されます。詳細については
Apple Event Manager に関する文献を参照してください。
transactionID - 通常は、値 kAnyTransactionID に設定されます。詳細については
Apple Event Manager に関する文献を参照してください。
result - 作成されたディスクリプタが保存される AEDesc レコードへのポインタ。
error - 発生するすべてのエラーに関する詳細情報が保存される AEBuildError 構造体へのポインタ。このパラメータは省略可能であり、この情報が必要なければ、代わりに、値 NULL を渡しても構いません。
paramsFmt - 作成する AppleEvent レコードについて記述する AEBuild の書式指定文字列。
... - paramsFmt パラメータに渡す書式指定文字列が必要とする任意の数のパラメータ。
結果:
AEBuildDesc の呼び出しの成否を数値で表す結果コード。値 AEBuildSyntaxNoErr (ゼロ)は、呼び出しの成功を意味します。error パラメータを使えば、ほかのエラーに関する情報を知ることができます。
|
重要:
アップルイベントレコードにあるダイレクトパラメータの識別子は、4 個のマイナス記号('----' )です。このマイナス記号は、AEBuild
文字列では特別な意味を持ち、ディスクリプタ文字列の中でアップルイベントのダイレクトパラメータを指すために使う場合は、必ず単一引用符で囲まなければなりません。
|
リスト 1 は、AEBuildAppleEvent ルーチンを使って[Open Documents]アップルイベントを作成する方法の例を示します。このコード例において作成されているイベントは、クリエータコード('MACS' )を使って、Finder アプリケーションを対象にしています。
リスト 1 AEBuildAppleEvent ルーチンを使った、[Open Documents]アップルイベント作成方法の例
|
AliasHandle first_file, second_file;
const OSType finderSignature = 'MACS';
AppleEvent event;
OSErr err;
FSRef file1ref;
FSSpec file2spec;
/* エイリアスを作成する...*/
err = FSNewAlias(NULL, &file1ref, &first_file);
if (err == noErr) {
err = NewAlias(NULL, &file2spec, &second_file);
if (err == noErr) {
err = AEBuildAppleEvent(
kCoreEventClass, kAEOpenDocuments,
typeApplSignature, &finderSignagure, sizeof(finderSignature),
kAutoGenerateReturnID, kAnyTransactionID,
&event, /* 作成するイベント */
NULL, /* エラー情報を必要としない */
"'----':[alis(@@), alis(@@)]", /* 書式指定文字列 */
first_file, /* 1 番目の @@ に対応するパラメータ */
second_file); /* 2 番目の @@ に対応するパラメータ */
|
先頭に戻る
AEBuildParameters
AEBuildParameters を 1 回以上呼び出し、既存のアップルイベントレコードに追加パラメータまたはプロパティを追加できます。アップルイベントレコードは、AECreateAppleEvent または
AEBuildAppleEvent を呼び出してあらかじめ作成しておかなければなりません。AECreateAppleEvent ルーチンの詳細については、
Apple Event Manager に関する文献を参照してください。
OSStatus AEBuildParameters(
AppleEvent* event,
AEBuildError* error, /* NULL の場合もある */
const char* format,
...);
注意:AEBuildParameters は、vAEBuildParameters という名前の varargs に相当する関数を持っています。
パラメータ:
event - 新規パラメータを追加する対象となる AppleEvent レコードへのポインタ。
error - 発生するすべてのエラーに関する詳細情報が保存される AEBuildError 構造体へのポインタ。このパラメータは省略可能であり、この情報が必要でなければ、代わりに、値 NULL を渡しても構いません。
format - 追加する AppleEvent パラメータを記述する AEBuild の書式指定文字列。
... - format パラメータで渡す書式指定文字列が必要とする任意の数のパラメータ。
結果:
AEBuildParameters の呼び出しの成否を数値で表す結果コード。値 AEBuildSyntaxNoErr (ゼロ)は、呼び出しの成功を意味します。error パラメータを使えば、その他のエラーに関する情報を知ることができます。
|
先頭に戻る
AEPrintDescToHandle
AEPrintDescToHandle は、アップルイベントディスクリプタレコードのために書式付き出力機能を提供します。AEDesc レコードを記述する情報は、専用の AEBuild * の構文に従った書式で返されます。この機能は、別のアプリケーションにより送信されたアップルイベントレコードの情報を見たり、アプリケーション自身により作成されたアップルイベントディスクリプタをデバッグしたりするのに有効です。次に AEPrintDescToHandle の定義を示します。
OSStatus AEPrintDescToHandle(
const AEDesc* desc,
Handle* result);
パラメータ:
desc - 出力するアップルイベントディスクリプタレコードへのポインタ。
result - ディスクリプタ文字列を含む、新規に作成されたメモリマネージャ 'Handle ' の格納場所へのポインタ。
結果:
AEPrintDescToHandle の呼び出しの成否を数値で表す結果コード。値 AEBuildSyntaxNoErr (ゼロ)は、呼び出しの成功を意味します。
|
AEPrintDescToHandle が、AEDesc 、AERecord 、または AEDescList を出力するように要求されたときの出力の書式は、AEBuildDesc が入力として受け付ける書式と同じです。出力時、AEPrintDescToHandle は、さまざまなタイプにタイプ変換された AERecords を識別しようとし、それらをタイプ変換済みレコードとして出力します。識別できなかったその他の構造体は、16 進数のデータとしてダンプ出力されます。 次に、3 つの項目からなるリストの AEPrintDescToHandle による出力例を示します。
[ "Mac OS X", 'null'(), 44]
|
ただし、
AppleEvent レコードの書式は少し異なります。次の例では、イベントクラスとイベント ID が文字列の開始位置に、パラメータのリストはレコードとして中括弧に囲まれて、またプロパティは識別子の前にアンパサンドを付けて出力されます。次に「Open Documents」アップルイベントの
AEPrintDescToHandle 出力の例を示します。
aevt¥odoc{ ----:"Mac OS X",
&addr:psn ($0000000000040001$),
&subj:'null'(),
&csig:magn($00010000$) }
|
AppleEvent レコードの出力は、AEBuild * ルーチン群が受け付ける構文とは違うので、この出力は AEBuildAppleEvent への入力としては使えません。
先頭に戻る
ディスクリプタ文字列の構文
ディスクリプタ文字列は、ヌルで終了する C 言語形式の文字列として提供されます。このライブラリの古い実装では、いつくかの言語記号として特別な MacRoman の文字が使われていました。これらの古い文字はまだサポートされていますが、さらに、代わりの新しい 7 ビットの ASCII 文字が追加されています。
今後のコードには、新しい推奨の 7 ビットの ASCII 文字を使った方がよいでしょう。
データタイプ
ディスクリプタ文字列の構文では、整数、4 文字のタイプコード、テキスト文字列、16 進データの 4 つの基本的なデータタイプがあります。表 2
は、構文に従って記述されたこれらのデータタイプの例をいくつか示します。
表 2 AEBuild の基本データタイプ
データタイプ
|
例
|
作成される AEDesc のタイプコード
|
説明
|
整数
|
1234 -5678
|
'shor' または 'long'
|
10 進数の数字の並びでマイナス記号が前に付くこともあります。
-32768 と 32767 の間の整数は、typeShortInteger タイプのディスクリプタにタイプ変換されます。この範囲外にある値は、typeLongInteger タイプに変換されます。実装が特定の数字タイプを要求する場合は、必ずタイプ変換を指定しなければなりません。
|
タイプコード
|
whos
longint
'long'
m
|
'enum' ('type' に変換するためにタイプ変換を使用)
|
タイプコードは、文字で始まり、任意の数の AEBuild 構文外の文字が続きます。最初の 4 文字だけが使用されます。タイプコードは、4 文字のコードにするために、切り捨てられたり、スペースで埋められたりします。
単一引用符ではさめば、AEBuild 構文の特殊文字を含めることができます。
アプリケーションとシステムソフトウェアが使用するタイプコードの定義の多くは、システムのヘッダファイル(<AEDataModel.h>、<AERegistry.h>、<AppleEvents.h>)にあります。
|
文字列
|
"A String"
"Multiple lines
are okay."
|
'TEXT'
|
二重引用符にはさまれた任意の文字の並び。作成された 'TEXT'
タイプのディスクリプタレコードには、終了のためのヌルの文字は含まれません。
|
16 進データ
|
$4170706C65$
$ 0102 03ff
e b 6 c $
|
?? (何らかのタイプにタイプ変換する必要があります)
|
ドル記号にはさまれた 16 進数で表された偶数桁の値。空白文字は無視されます。16 進データには固有のタイプはありません。そのため、使用するときは必ず、何らかのタイプにタイプ変換しなければなりません。
|
|
重要:
カンマ、括弧、中括弧、末尾以外でのスペースなどの特殊文字を含むコード、または - のような特殊文字で始まるタイプコードには注意します。これらの文字は、AEBuild では構文の一部として使用されます。タイプコードでこれらの特殊文字を使う必要がある場合は、そのタイプコードを単一引用符で囲みます。
|
先頭に戻る
タイプ変換
表 2 に示したどの基本データタイプにも(16 進データ以外)、作成されるディスクリプタレコードのタイプを定義する、データタイプ自身に対応する固有のデータタイプがあります。同じデータを含む異なるタイプのディスクリプタが必要な場合は、タイプ変換の構文を使うことによって、それを作成するように AEBuild * に指示することができます。タイプ変換構文の要素は、希望のタイプコードと使用する基本データタイプです。これらの要素は、次の書式で指定します(希望のタイプコードの後に、括弧で囲まれた基本のデータタイプを続けます)。
<希望のタイプコード> ( <任意のデータタイプ> )
|
この種類のタイプ変換を実行するように AEBuild に指示しても、インストール済みのタイプ変換ハンドラは呼び出されません(数値のタイプ変換は例外)。むしろ、このタイプ変換構文は AEBuild に、まったく同じデータを含む、型の異なるディスクリプタレコードを作成するように指示します。次にいくつか例を示します。
sing(123)
type(line)
hexd("a string")
'blob'($4170706C65$)
'utxt'($0048 0045 004C 004C 004F$)
|
インストール済みのアップルイベントタイプ変換ハンドラは、数値タイプに対してのみ呼び出されます(これは、errAECoercionFail エラーを返すことができる唯一のケースです)。その他の
AEBuild タイプ変換ハンドラは、作成されたディスクリプタレコードにディスクリプタのタイプフィールドを設定する以外のことは何も行いません。
次の構文の 1 つを利用することにより、タイプ変換構文を使って、空の(つまり 'null' )のディスクリプタレコードを作成できます。これらの構文はいずれも、長さゼロのデータを持つ空のディスクリプタレコードを作成します。
最後の形式 () は、ほかの形式よりわかりにくいですが、空の(つまり 'null')のディスクリプタを作成するのに使用できます。
先頭に戻る
複雑なデータタイプ
アップルイベントディスクリプタには、多数のほかのアップルイベントディスクリプタレコードを含みうる、2 つのタイプの複雑なデータ構造体が含まれている場合があります。リストには、名前が示すとおり、ディスクリプタレコードのリストが含まれます。レコードには、名前が 4 文字のタイプコードで値がディスクリプタレコードである名前と値のペアの集合が含まれます。これらの複雑なタイプはどちらも、アップルイベントディスクリプタレコード内に含まれるので、再帰的に使用できます。
つまり、リストにはリストまたはレコードを、レコードにはレコードまたはリストを含めることができます。次の 2 節では、これらの複雑なタイプのための AEBuild の宣言をさらに詳しく説明します。
リスト
アップルイベントリストディスクリプタには、0 個以上のアップルイベントディスクリプタが含まれています。それらのディスクリプタすべてが同じタイプ、または同じ書式でなければならないという要件はありません。AEBuild のディスクリプタ文字列においては、ディスクリプタのリスト(空の場合もあります)は、大括弧の間に、ディスクリプタレコードをカンマで区切って指定します。
[ <ディスクリプタ>, <ディスクリプタ>... ]
|
この構文では、AEDescList ディスクリプタレコード('list' タイプの AEDesc レコード)が作成されます。次に、リストを定義する有効な AEBuild ディスクリプタ文字列の例を示します。
[123, -456, "et cetera"]
[sing(1234), long(CODE)]
[["wheels", "within wheels"]]
[sing(1234), long(CODE), [[123, -456, "et cetera"], "within wheels"]]
[]
|
リストを別のタイプに変換することはできません。リストのディスクリプタタイプは常に 'list' に設定されています。リストを別のタイプに変換しようとする記述を含む AEBuild ディスクリプタ文字列は機能しません。
先頭に戻る
レコード
ディスクリプタレコードは、順不同の名前と値のペアの集合です。名前と値の各ペアにおいて、名前は、4 文字のタイプコードにより表され、値は任意の有効なディスクリプタです。AEBuild のディスクリプタ文字列の構文において、
AERecord は、中括弧の間に、名前と値のペアのリストをカンマで区切って宣言します。
{ <名前> : <値>, <名前> : <値>... }
|
名前とそれに対応する値とは、コロン(: )で区切ります。デフォルトでは、レコードのタイプは、'reco' に設定されていますが、レコード定義の前にそのレコードに使用するタイプコードを指定することで、どのタイプにもタイプ変換することができます。
<タイプコード> { <名前> : <値>, <名前> : <値>... }
|
次に、有効な AERecord 宣言を含む AEBuild
のディスクリプタ文字列の例を示します。
{x: 100, y:-100}
{'origin': {x: 100, y:-100}, extent: {x: 500, y:500},
cont: [1, 5, 25]}
{}
rang{ star: 5, stop: 6}
|
デフォルトのレコードタイプは、'reco' です。レコード構造体は、その前にタイプコードを指定することによってどのタイプにも変換できます。たとえば、次のようにします。
AERecord は、'indx' または
'whos' などの別のタイプに変換するのが一般的ですが、AERecords を、'long' または 'TEXT' などの一般的なデータタイプに変換するのは避けた方がよいでしょう。なぜなら、ほかのアプリケーションおよび AEPrint のような機能さえ混乱させてしまうからです。
先頭に戻る
パラメータ置換
AEBuild * ルーチン群は、AEBuild * ルーチンに渡された省略可能な引数を読み取るのに使える強力な機能を備えた 2 つの置換演算子のセットを提供しています。標準の C ライブラリの printf ルーチンによって提供される機能と非常に良く似た方法を使用して、AEBuild * ルーチンは、AEBuild ディスクリプタ文字列とともに可変長のパラメータリストを受け付けるようになります。可変長のパラメータリストに含まれている引数は、AEBuild のディスクリプタ文字列中の置換演算子の配置に従って、作成されるディスクリプタレコードに組み込まれます。
置換演算子は、AEBuild ディスクリプタ文字列の中のディスクリプタを定義できる場所ならどこにでも置けます作成される値のタイプ(および想定されるパラメータのタイプ)は、AEBuild ディスクリプタ文字列中の置換演算子のコンテキストに依存します。通常は、置換演算子に適用されるタイプ変換演算子が、作成されるディスクリプタのタイプとコマンドラインパラメータとして想定されるデータのタイプを決定します。
この特別な置換演算子は、@ と @@ です。
表 3
に、これらの演算子が AEBuild にどのように解釈されるかを詳しく示します。
表 3 タイプ変換と引数のタイプに関する要件
指定されるタイプ変換
|
想定されるパラメータのタイプ
|
例
|
説明
|
タイプ変換なし
|
AEDesc*
|
AEDesc mydesc;
AEBuild(..., "@",
&mydesc);
|
@ は、ディスクリプタパラメータで置き換えられます。この場合、@@ は指定できません。
|
数値(bool、shor、long、sing、doub、exte)
|
short、short、long、float、short double、double
|
AEBuild([....]
"long(@)",
44);
|
数値タイプは、コマンドライン上にそのまま入力されます。
|
TEXT
|
char*
|
AEBuild([....]
"TEXT(@)",
"hello world");
|
ヌルで終了する C 文字列へのポインタ。'TEXT(@) ' は、C 言語文字列からのテキストすべて(終了を表す値ゼロのバイトを除く)を含む 'TEXT' タイプのディスクリプタで置き換えられます。この場合、'@@' は指定できません。
|
その他のすべてのタイプ
|
(長さ、ポインタ)のペアまたは Handle
|
MyType myVar;
AEBuild([....]
"myst(@)",
sizeof(myVar),
&myVar);
|
@ に対応するデータは、2 つのパラメータ、つまりバイト数を指定する long 型の整数値とその後に続くバイトデータへのポインタから読み込まれます。@@ が指定されている場合は、
データはパラメータとして渡された、Carbon Memory Manager の Handle 値から読み込まれます。
|
|
先頭に戻る
gdb での AEPrint* の利用
イベントハンドラおよび AppleScript スクリプトを記述するときに多くの場合は、アプリケーション間で送受信されるアップルイベントの形式がわかると役に立ちます。本節では、Mac OS X アプリケーションから送られたイベントの形式を、gdb の中で AEPrintDescToHandle ルーチンを使って表示する方法を示します。
gdb は、ルーチンの呼び出しを可能にする call 機能を提供しています。次のリスト 2 に示すスクリプトは、AEPrintDescToHandle を呼び出して、AppleEvent を gdb の Terminal に書式付きで出力するために使用するものです。
以降の例では、このスクリプトが、'gdb-aedesc' という名前のファイルに保存されることを前提にしています。しかし、gdb を開始したときに、このスクリプトが必ず自動的にロードされるようにするには、このスクリプトを
‾/.gdbinit ファイルに保存します。
リスト 2 AEDesc レコードを書式付きで出力するための gdb スクリプト
|
define aedesc
call (void *) malloc(4)
set $aed_malloc=$
call (long) AEPrintDescToHandle($arg0, $aed_malloc)
if $ == 0
printf "desc @ %p = {¥n type = '%.4s'¥n storage (%p) = %s¥n}¥n", ¥
$arg0, $arg0, ((long *) $arg0)[1], **(char ***) $aed_malloc
call (void) DisposeHandle(*(char ***) $aed_malloc)
else
printf "aedesc failed: error %d.¥n", $
end
call (void) free($aed_malloc)
end
|
Mac OS X で、スクリプトエディタを実行しているときに、リスト 3 に示すスクリプトを、スクリプトエディタのウィンドウの 1 つに入力し、構文を 2、3 度チェックし、何度か実行させて正しく機能することを検証したとします。スクリプトを 2、3 回実行した後、このスクリプトの実行時に送られるアップルイベントについてより詳しい情報を調べたいと思っています。
リスト 3 簡単なスクリプト
|
tell application "Finder"
activate
open "Mac OS X"
end tell
|
リスト 4 で示される Terminal セッションのログは、gdb スクリプト aedesc を使って、スクリプトの実行時にスクリプトエディタによって送信されるアップルイベントの詳細情報を知る方法を示します。スクリプトに追加したコメントは、先頭に ## の文字を置いています。
リスト 4 gdb セッションログ
|
## Terminal ウィンドウで、gdb を開始する
[neithermac:/] apple% gdb
GNU gdb 5.0-20001113 (Apple version gdb-203) ([....] GMT 2001) (UI_OUT)
Copyright 2000 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "powerpc-apple-macos10".
## 自分の aedesc スクリプトを読み込む。通常は、「source」と入力し、その後
## このスクリプトのファイルアイコンを Terminal ウィンドウにドラッグアンドドロップする。
## ただし、このスクリプトを自分の gdb 設定に追加することも可能(「man gdb」を参照)
## スクリプトは、ディスクリプタを書式付きで出力するための
## AEPrintDescToHandle の呼び出しに使えるコマンド、'aedesc' を定義する
(gdb) source /Users/apple/gdb-aedesc
## 次にスクリプトエディタのプロセスにアタッチする
## このプロセスは、gdb セッションの前に作成した 1312 というプロセスの ID を持つ。
## 実行プロセスのプロセス ID は、「top -l」または「ps -aux」を使って
## を調べることができる
(gdb) attach 1312
Reading symbols for shared libraries . done
Reading symbols for shared libraries ..................................
.................... done
[Switching to process 1312 thread 0x1603]
## その後、AESend にブレークポイントを設定して、出力イベントをトラップできるようにする
(gdb) break AESend
Breakpoint 1 at 0x731ddbec
## また、スクリプトエディタによる実行の継続を許可するように gdb に指示する
(gdb) continue
Continuing.
## ここで、スクリプトエディタを使って、元に戻る
## スクリプトを実行するために「run」ボタンをクリックする
## イベント送信時に停止
Breakpoint 1, 0x731ddbec in AESend ()
## スクリプトにディスクリプタを書式付きで出力するように要求する($r3 を使用)
(gdb) aedesc $r3
$1 = (void *) 0x1bb8310
$2 = 0
desc @ 0xbfffe398 = {
type = 'aevt'
storage (0x150d858) = misc¥actv{ &addr:psn ($0000000000040001$),
&subj:'null'(), &csig:magn($00010000$) }
}
## また、スクリプトエディタによる実行の継続を許可するように gdb に指示する
(gdb) continue
Continuing.
## [Open Documents]イベントで停止
Breakpoint 1, 0x731ddbec in AESend ()
## ディスクリプタを書式付きで出力するようにスクリプトに要求する($r3 を使用)
(gdb) aedesc $r3
$3 = (void *) 0x16ea1c0
$4 = 0
desc @ 0xbfffe2c8 = {
type = 'aevt'
storage (0x150d858) = aevt¥odoc{ ----:"Mac OS X",
&addr:psn ($0000000000040001$), &subj:'null'(),
&csig:magn($00010000$) }
}
## また、スクリプトエディタによる実行の継続を許可するように gdb に指示する
(gdb) continue
Continuing.
|
この手法は、任意の Mac OS X アプリケーションが送信するアップルイベントを調べるために使えます。
先頭に戻る
ディスクリプタ文字列の文法
次に、AEBuild のディスクリプタ文字列に使用される Backus Naur Form (BNF) の文法定義を示します。
# 注意:構文規則の間に挿入されたコメントの前には # 文字が置かれる
# これらのコメントは、BNF ではない
# AEBuildAppleEvent の構文規則
AEBuild-apple-event-expression ::= <event-keyword-list>
# event-keyword-list - 0 個以上のイベント/キーワードのペアのリスト
# カンマにより区切られる
event-keyword-list ::= <event-keyword-pair> , <event-keyword-list>
event-keyword-list ::= <event-keyword-list>
event-keyword-list ::=
# event-keyword-pair 識別子/オブジェクトのペア
# このペアの前には、省略可能なパラメータであることを示すチルド記号、‾ が置かれる
event-keyword-pair ::= ‾ <identifier> : <object>
event-keyword-pair ::= <identifier> : <object>
#AEBuildDesc の構文規則
AEBuild-expression ::= <object>
object ::= <data> # Single AEDesc; (データ)のショートカット
object ::= <structure> # タイプ変換されていない構造体
object ::= <identifier> <structure> # cほかのタイプに変換される
structure ::= ( <data> ) # 1 つの AEDesc
structure ::= [ <object-list> ] # AEDescList タイプ
structure ::= { <keyword-list> } # AERecord タイプ
# 0 個以上の、カンマで区切られたオブジェクトのリスト
object-list ::= <object-list> , object>
object-list ::= <object>
object-list ::=
# 0 個以上の、カンマで区切られたキーワード/値のペアのリスト
keyword-list ::= <keyword-list> , <keyword-pair>
keyword-list ::= <keyword-pair>
keyword-list ::=
keyword-pair ::= <identifier> : <object> # keyword/value pair
# @ と @@ は、ディスクリプタの作成時に、
# ディスクリプタに AEBuild パラメータを読み込むために使用する特別な記号
data ::= @ # AEBuild パラメータからデータを読み込む
data ::= @@ # AEBuild ハンドルのパラメータからデータを読み込む
data ::= <integer> # タイプ変換されていなければ、'shor' タイプまたは 'long' タイプ
data ::= <identifier> # タイプ変換されていなければ、4 文字のタイプコード('type')
data ::= <string> # タイプ変換されていなければ、ヌルで終了されないテキスト('TEXT')
data ::= <hex-string> # 未加工の 16 進数のデータ。何らかのタイプに変換する必要がある!
data ::= # 空のヌルのデータ。null() によるタイプ変換に有効
integer ::= - <number>
integer ::= <number>
number ::= <number> <digit>
number ::= <digit>
digit ::= 0 .. 9
# 単一引用符で囲まれていない場合には、識別子の中に
# スペースを含めることはできない
# 識別子は、ちょうど 4 文字になるように、AEBuild およびその関連ルーチンにより、
# スペースが埋め込まれるか、切り捨てが行われる
identifier ::= <first-ident-letter> <ident-letter-list>
identifier ::= ' <any-letter letter-list> ' # straight quotes (preferred)
identifier ::= ‘ <any-letter letter-list> ‘ # curly quotes
ident-letter-list ::= <ident-letter-list> <ident-letter>
ident-letter-list ::= <ident-letter>
ident-letter-list ::=
first-ident-letter ::= alphabetic characters
# AEBuild 言語の特殊文字は、識別子の中に含めることはできない
# 特殊文字を含む識別子を使用するには、
# その識別子を単一引用符で囲む
ident-letter ::= any printable character excluding spaces
and special AEBuild characters
string ::= " <letter-list> " # 直線状の二重引用符(推奨)
string ::= “ <letter-list> ” # カール状の二重引用符
letter-list ::= <letter-list> <any-letter>
letter-list ::= <any-letter>
letter-list ::=
any-letter ::= any printable character including spaces
and special AEBuild characters.
# 16 進数の場合は、数字の間に空白文字を含めることができる
# したがって書式を整えるために自由に空白文字を追加できる
hex-string ::= $ <hex-digit-list> $ # ドル記号の引用符(推奨)
hex-string ::= « <hex-digit-list> » #フランス語の引用符
hex-digit-list ::= <hex-digit-list> <hex-digit-pair>
hex-digit-list ::= <hex-digit-pair>
hex-digit-list ::=
hex-digit-pair ::= <hex-digit> <hex-digit>
hex-digit ::= digits 0 .. 9 or letters A .. F (大文字小文字は無視される)
|
先頭に戻る
ダウンロード
先頭に戻る
|